package com.flyqiu.common.property;

import com.flyqiu.common.std.FlyQiuBooleanFun;
import com.flyqiu.common.tools.FlyQiuCollectionTools;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.function.Function;

/**
 * 表示一个基本属性的接口。
 * <p>
 * 此接口定义了属性的基本操作，包括读取、写入、静态属性判断、获取名称和类型等。
 */
public interface FlyQiuBaseProperty {

    /**
     * 判断属性是否可读。
     *
     * @return 如果属性可读，则返回 true；否则返回 false
     */
    boolean isRead();

    /**
     * 判断属性是否可写。
     *
     * @return 如果属性可写，则返回 true；否则返回 false
     */
    boolean isWrite();

    /**
     * 判断属性是否为静态属性。
     *
     * @return 如果属性为静态属性，则返回 true；否则返回 false
     */
    boolean isStatic();

    /**
     * 获取属性的名称。
     *
     * @return 属性名称
     */
    String getName();

    /**
     * 获取属性的数据类型。
     *
     * @return 属性的数据类型
     */
    Class<?> getType();

    default <T extends Annotation> T getAnnotation(Class<T> clazz) {
        Function<Annotation, T> mapper = annotation -> {
            if (!clazz.isInstance(annotation)) {
                return null;
            }
            return clazz.cast(annotation);
        };
        FlyQiuBooleanFun<Annotation> filter = clazz::isInstance;
        List<T> annotations = getAnnotations(filter, mapper);
        if (FlyQiuCollectionTools.isEmpty(annotations)) {
            return null;
        }
        return annotations.get(0);
    }

    default List<Annotation> getAnnotations() {
        Function<Annotation, Annotation> mapper = annotation -> annotation;
        FlyQiuBooleanFun<Annotation> filter = annotation -> true;

        return getAnnotations(filter, mapper);
    }


    <T extends Annotation> List<T> getAnnotations(FlyQiuBooleanFun<Annotation> filter, Function<Annotation, T> valueMapper);

    /**
     * 获取属性的值。
     *
     * @param obj 对象实例
     * @return 属性的值
     */
    Object getValue(Object obj);

    /**
     * 设置属性的值。
     *
     * @param obj 对象实例
     * @param val 属性的新值
     */
    void setValue(Object obj, Object val);
}
